// package 数据库底层，主要包括数据库初始化、配置
/*
    每个 Go 包中的文件都可以包含一个或多个 init 函数。这些 init 函数在程序执行前被自动调用有且只有一次，用于执行包的初始化操作
    若一个源文件包含多个init函数，会按定义的顺序执行
	若一个包的不同源文件均包含init函数，会按源文件字母顺序执行
	不同包的init函数按包之间的依赖关系执行
    若该包没有被应用，则该包的init函数不会被执行
*/
package db

import (
	"osiris/config"
	"osiris/logger"
	"osiris/model"
	"time"

	"fmt"

	"gorm.io/driver/mysql"
	"gorm.io/gorm"
)

var (
	MySQL *gorm.DB
)

func init() {

}

// InitMySQL 初始化节点对应的数据库，包括数据库创建、表创建
//
//	@param codeName 节点代号
//	@return error 遇到的第一个错误
func InitMySQL(codeName string) error {
	preMySQL, err1 := gorm.Open(mysql.Open(config.BaseMySQLConfig), &gorm.Config{})
	if err1 != nil {
		logger.Error(map[string]interface{}{"[db] [Init] Mysql connect error": err1})
	}

	fmt.Printf("mysql %s\n", codeName)
	err2 := preMySQL.Exec("CREATE DATABASE IF NOT EXISTS " + codeName).Error
	if err2 != nil {
		logger.Error(map[string]interface{}{"[db] [Init MySQL] create database " + codeName: err2})
		return err2
	}

	preSQLDB, err3 := preMySQL.DB()
	if err3 != nil {
		logger.Error(map[string]interface{}{"[db] [Init MySQL] preMySQL.DB()": err3})
		return err3
	}
	preSQLDB.Close()

	//连接codeName对应的数据库
	var err4 error
	mySQLconfig := config.BaseMySQLConfig + codeName
	MySQL, err4 = gorm.Open(mysql.Open(mySQLconfig), &gorm.Config{})
	if err4 != nil {
		logger.Error(map[string]interface{}{"[db] [Init] Mysql connect error": err4})
	}

	sqlDB, err5 := MySQL.DB()
	if err5 != nil {
		logger.Error(map[string]interface{}{"[db] [Init MySQL] MySQL.DB()": err5})
		return err5
	}
	//设置空闲连接池中连接的最大数量
	sqlDB.SetConnMaxIdleTime(10)
	//设置打开数据库连接的最大数量
	sqlDB.SetMaxOpenConns(100)
	//设置连接可复用的最大时间
	sqlDB.SetConnMaxLifetime(time.Hour)

	//AutoMigrate: 表不存在的话就根据model创建
	err6 := MySQL.AutoMigrate(&model.AddrModel{})
	if err6 != nil {
		logger.Error(map[string]interface{}{"[db] [Init MySQL] auto migrate table addr": err6})
		return err6
	}

	err7 := MySQL.AutoMigrate(&model.PubKeyModel{})
	if err7 != nil {
		logger.Error(map[string]interface{}{"[db] [Init MySQL] auto migrate table addr": err7})
		return err7
	}

	err8 := MySQL.AutoMigrate(&model.BlockHeaderModel{})
	if err8 != nil {
		logger.Error(map[string]interface{}{"[db] [Init MySQL] auto migrate table block": err8})
		return err8
	}

	err9 := MySQL.AutoMigrate(&model.AccountModel{})
	if err9 != nil {
		logger.Error(map[string]interface{}{"[db] [Init MySQL] auto migrate table account": err9})
		return err9
	}

	err10 := MySQL.AutoMigrate(&model.LocalModel{})
	if err10 != nil {
		logger.Error(map[string]interface{}{"[db] [Init MySQL] auto migrate table local": err10})
		return err10
	}

	err11 := MySQL.AutoMigrate(&model.LocalQueuedModel{})
	if err11 != nil {
		logger.Error(map[string]interface{}{"[db] [Init MySQL] auto migrate table localqueued": err11})
		return err11
	}

	err12 := MySQL.AutoMigrate(&model.TxModel{})
	if err12 != nil {
		logger.Error(map[string]interface{}{"[db] [Init MySQL] auto migrate table txs": err12})
		return err12
	}

	return nil
}
